import os
import argparse
from src.generate_code import (
    Code, from_luhn_in_ean13, generate, ean13, luhn
)
from src.generate_html import gen_templete
from src.generate_img import generate_img, return_bytes
from src.utils import counter, read_file, yield_from


class Cli():
    def __init__(self):
        self.parser = argparse.ArgumentParser(
            description="Barcode Generate")
        self.subparsers = self.parser.add_subparsers(
            help='sub-command help', dest="gencode")
        self.generate_code()
        self.generate_img()
        self.generate_html()

    def generate_code(self):
        gen_code = self.subparsers.add_parser(
            'gencode', help='Генерация баркодов')
        gen_code.add_argument(
            '-cm', '--code_dip',
            help="Код магазина",
            type=int
        )
        gen_code.add_argument(
            '-cc', '--code',
            help='Добавочный код после кода магазина. Учитывайте длину.',
            type=int, required=True)
        gen_code.add_argument(
            '-m', '--method',
            help='Метод генерации. Example: -m ean13',
            choices=["ean13", "luhn", "counter"], default="counter",
            type=str
        )
        gen_code.add_argument(
            '-s', '--shag',
            help="Шаг при генерации",
            type=int, default=1)
        gen_code.add_argument(
            '-o', '--otstup',
            help="Сколько отступит до заданого",
            type=int, default=0)
        gen_code.add_argument(
            '-c',
            '--count',
            help="Количество",
            type=int, default=10)
        gen_code.set_defaults(func=self.generate_code_callback)

    @staticmethod
    def generate_code_callback(arguments: argparse.Namespace):
        for code in generate(
            check_method={
                "ean13": ean13,
                "luhn": luhn,
                "counter": counter}.get(
                arguments.method, "ean13"),
            otstup=arguments.otstup or 0,
            shag=arguments.shag or 1,
            count=arguments.count or 50)(
                code=Code(
                    code_dip=str(arguments.code_dip),
                    code=int(arguments.code)
                )):
            print(code)

    def generate_img(self):
        gen_img = self.subparsers.add_parser(
            'genimg', help='Генерация Изображений баркодов')
        gen_img.add_argument(
            '-c', '--code',
            help='Коды для генерации. Example: -c 9900021000021 9900021000113',
            default=[],
            type=str,
            nargs="*"
        )
        gen_img.add_argument(
            '-cp', '--code_path',
            help='Путь до .txt файла с кодами генерации. Example: -cp result.txt result1.txt',
            default=[],
            type=str,
            required=True,
            nargs="*"
        )
        gen_img.add_argument(
            '-p', '--path',
            help='Директория куда сохранить. Example: -p result',
            type=str,
            default=os.getcwd()
        )
        gen_img.set_defaults(func=self.generate_img_callback)

    @staticmethod
    def generate_img_callback(arguments: argparse.Namespace):

        for code in yield_from(
            arguments.code if arguments.code else (),
            read_file(arguments.code_path) if arguments.code_path else ()
        ):
            try:
                img_code = generate_img(code)
                save_imga_path = arguments.path + f"/{code}.png"
                img_code.save(save_imga_path)
                print(f"Code: {code} generate img: {save_imga_path}")
            except Exception as error:
                print(f"Error: {code} {error}")

    @staticmethod
    def generate_html_callback(arguments: argparse.Namespace):
        try:
            gen_templete(
                yield_from(
                    arguments.code if arguments.code else (),
                    read_file(
                        arguments.code_path) if arguments.code_path else ()
                ), arguments.templete_path
            )
        except Exception as error:
            print(f"Error: {error}")
        else:
            print(f"Templete save: {arguments.template_path}")

    def generate_html(self):
        gen_html = self.subparsers.add_parser(
            'genhtml', help='Генерация шаблона с изображениями')
        gen_html.add_argument(
            '-c', '--code',
            help='Коды для генерации. Example: -c 9900021000021 9900021000113',
            default=[],
            type=str,
            nargs="*"
        )
        gen_html.add_argument(
            '-cp', '--code_path',
            help='Путь до .txt файла с кодами генерации. Example: -cp result.txt result1.txt',
            default=[],
            type=str,
            nargs="*"
        )
        gen_html.add_argument(
            '-t', '--templete_path',
            help='Путь до шаблона, который будет использован. Example: -t first.html',
            default='templates/1.html',
            type=str,
        )
        gen_html.add_argument(
            '-p', '--path',
            help='Директория куда сохранить. Example: -p result.html',
            type=str,
            default=os.getcwd() + "result.html"
        )
        gen_html.set_defaults(func=self.generate_html_callback)

    def __call__(self):
        try:
            arguments = self.parser.parse_args()
            arguments.func(arguments)
        except Exception as error:
            print(error)


def main():
    _cli = Cli()
    _cli()


if __name__ == '__main__':
    main()
